package main.parsers.utils;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.sql.Date;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;

import javax.swing.ImageIcon;

import main.database.Database;
import main.parsers.AbstractParser;

public abstract class Utils extends AbstractParser
{
	static final String refpath = site + "/referee/24985/";
	static final String calendar = site + "/calendar/";
	
	public static Map<String, Integer> makeReferees()
	{
		Map<String, Integer> referees = loadReferees();
		Map<String, Integer> cities = loadCities();
		boolean linesman = false;
		boolean changed = false;
		
		BufferedReader reader = getReader(refpath);
		String line;
		try 
		{
			while ((line=reader.readLine()) != null)
			{	
				if (line.contains("<h4>"))
				{		
					while ((line=reader.readLine()) != null)
					{
						if (line.contains("table"))
						{
							int length = getRefColCount(line);
							Referee[] refs = new Referee[length];
							pass(reader, 1);
							
							for (int i = 0; i < length; i++)
							{
								line = pass(reader, 2);
								ImageIcon photo = getImage(line);
								refs[i].setPhoto(photo);
							}
							
							pass(reader, 2);
							
							for (int i = 0; i < length; i++)
							{
								line = pass(reader, 2);
								String surname = getTagContent(line);
								line = pass(reader, 2);
								String name = getTagContent(line);
								refs[i].setFullname(surname + ' ' + name);
							}
							
							pass(reader, 2);
							
							for (int i = 0; i < length; i++)
							{
								line = pass(reader, 2);
								String city = getTagContent(line);
								if (!cities.containsKey(city))
								{
									makeCity(city);
									cities = loadCities();
								}
								refs[i].setCity(city);
							}
							
							pass(reader, 3);
							
							for (int i = 0; i < length; i++)
							{
								line = pass(reader, 1);
								String year = getTagContent(line);
								refs[i].setYear(year);
								
								line = pass(reader, 1);
								String international = getTagContent(line);
								if (international.equals("&nbsp;")) 
								{
									refs[i].setInternational(false);
								}
								else
								{
									refs[i].setInternational(true);
									pass(reader, 2);
								}
								
								refs[i].setLinesman(linesman);
							}
							
							for (int i = 0; i < length; i++)
							{
								if (!referees.containsKey(refs[i].getFullname()))
								{
									makeReferee(refs[i]);
									changed = true;
								}
							}
						}
						
						if (line.contains("<div align=\"center\">")) break;
					}			
					
					linesman = true;
				}
			}
			
			if (changed) referees = loadReferees();
			
		}
		catch (IOException e) 
		{
			System.err.println("Unable to read page");
			e.printStackTrace();
		}
		finally
		{
			closeReader(reader);
		}
		
		return referees;
	}
	
	public static void makeSeasons()
	{
		BufferedReader reader = getReader(calendar);
		String line;
		try
		{
			while ((line=reader.readLine()) != null)
			{
				if (line.contains("content_top_menu"))
					while (!(line=reader.readLine()).contains("</ul>")) makeSeason(line);
			}
		}
		catch (IOException e) 
		{
			System.err.println("Unable to read page");
			e.printStackTrace();
		} 
		catch (Exception e) 
		{
			System.err.println("Unable to add season");
			e.printStackTrace();
		}
		finally
		{
			closeReader(reader);
		}
	}
	
	private static boolean checkSeason(Season season) throws Exception
	{
		Object[] params = { season.getId() };
		ResultSet rs = Database.getInstance().executeQuery("check.country", params);
		boolean exists = rs.next();
		rs.close();
		return exists;
	}
	
	private static boolean makeSeason(String line) throws Exception
	{
		if (line.contains("documents")) return false;
		
		int start = line.indexOf('/') + 9;
		int end = line.indexOf('/', start);
		int id = Integer.parseInt(line.substring(start, end));
		
		line = getTagContent(line);
		int pos = line.lastIndexOf(' ');
		
		String type = line.substring(0, pos);
		String year = line.substring(pos + 1);
		Season season = new Season(id, type, year);
		if (!checkSeason(season))
		{
			Object[] params = { season.getId(), season.getType(), season.getYear() };
			return Database.getInstance().executeChange("insert.season", params) > 0;
		}
		return false;
	}
	
	public static Map<String, Integer> loadReferees()
	{
		Map<String, Integer> referees = new HashMap<String, Integer>();
		
		try
		{
			ResultSet rs = Database.getInstance().executeQuery("select.referees", null);
			while (rs.next())
			{
				referees.put(rs.getString("fullname"), rs.getInt("id"));
			}
		}
		catch (Exception e) 
		{
			System.err.println("Unable to get referees from database");
			e.printStackTrace();
		}
		
		return referees;
	}
	
	public static Map<String, Integer> loadCities()
	{
		Map<String, Integer> cities = new HashMap<String, Integer>();
		
		try
		{
			ResultSet rs = Database.getInstance().executeQuery("select.cities", null);
			while (rs.next())
			{
				cities.put(rs.getString("city"), rs.getInt("id"));
			}
		}
		catch (Exception e) 
		{
			System.err.println("Unable to get cities from database");
			e.printStackTrace();
		}
		
		return cities;
	}
	
	public static Map<String, Integer> loadStates()
	{
		Map<String, Integer> states = new HashMap<String, Integer>(4);
		
		try
		{
			ResultSet rs = Database.getInstance().executeQuery("select.states", null);
			while (rs.next())
			{
				states.put(rs.getString("short"), rs.getInt("id"));
			}
		}
		catch (Exception e) 
		{
			System.err.println("Unable to get states from database");
			e.printStackTrace();
		}
		
		return states;
	}
	
	private static boolean makeCity(String city)
	{
		return false;
	}
	
	private static boolean makeReferee(Referee ref)
	{
		try
		{
			ByteArrayOutputStream photo = new ByteArrayOutputStream();
			ObjectOutputStream out = new ObjectOutputStream(photo);
			out.writeObject(ref.getPhoto());
			
			Object[] params = { ref.getFullname(), ref.getYear(), ref.getCity(), ref.isInternational(), ref.isLinesman(), photo.toByteArray() };
			
			return Database.getInstance().executeChange("insert.referee", params) > 0;
		}
		catch (Exception e) 
		{
			System.err.println("Unable to add referee");
			e.printStackTrace();
		}
		return false;
	}
	
	private static int getRefColCount(String line)
	{
		int start = line.indexOf("width") + 7;
		int end = line.indexOf('"', start);
		int width = Integer.parseInt(line.substring(start, end));
		return width / 120;
	}
}
